package mylab.starters.mybatis.interceptor.impl.tenant.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import mylab.common.context.TenantContext;
import mylab.starters.mybatis.interceptor.OrderlyInterceptor;
import mylab.starters.mybatis.config.tenant.TenantMode;
import mylab.starters.mybatis.config.tenant.TenantProperties;
import mylab.starters.mybatis.interceptor.impl.tenant.TenantInterceptor;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.NullValue;
import net.sf.jsqlparser.expression.StringValue;

/**
 * COLUMN 模式插件
 */
public class TenantColumnModeInterceptor extends TenantLineInnerInterceptor
        implements TenantInterceptor {

    TenantProperties.Column column;

    public TenantColumnModeInterceptor(TenantProperties.Column column) {
        super(new LineHandler(column));
        this.column = column;
    }

    @Override
    public int getOrder() {
        return OrderlyInterceptor.TenantColumn;
    }

    @Override
    public String getDescription() {
        return "租户插件-字段隔离";
    }

    @Override
    public TenantMode getTenantMode() {
        return TenantMode.COLUMN;
    }

    static class LineHandler implements TenantLineHandler {
        TenantProperties.Column column;

        public LineHandler(TenantProperties.Column column) {
            this.column = column;
            Assert.notBlank(column.getTenantColumn(), "无效的租户ID字段");
        }

        @Override
        public Expression getTenantId() {
            String tenantId = TenantContext.getTenantId();
            if (!CharSequenceUtil.isEmpty(tenantId)) {
                //当前会话不是租户登录，则直接返回
                return new StringValue(tenantId);
            }
            return new NullValue();
        }

        /**
         * 获取多租户的字段名
         *
         * @return String
         */
        @Override
        public String getTenantIdColumn() {
            return column.getTenantColumn();
        }

        /**
         * 过滤不需要根据租户隔离的表
         * 这是 default 方法,默认返回 false 表示所有表都需要拼多租户条件
         *
         * @param tableName 表名
         */
        @Override
        public boolean ignoreTable(String tableName) {
            return column.getIgnoreTables().stream().anyMatch(
                    (t) -> t.equalsIgnoreCase(tableName)
            );
        }
    }
}
